package com.my.jli.util;

import lombok.extern.slf4j.Slf4j;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName MyZipUtil
 * @Description 压缩文件工具类
 * @Author MaYu
 * @Date 2022/5/10 20:40
 * @Version 1.0
 **/
@Slf4j
public class MyZipUtil {

    /**
     * 压缩成zip
     * @param srcDir 压缩文件夹路径
     * @param out 压缩文件输出流
     * @throws Exception 异常
     */
    public static void toZip(String srcDir, OutputStream out) throws Exception{
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null;
        try {
            zos = new ZipOutputStream(out);
            File sourceFile = new File(srcDir);
            compress(sourceFile, zos, sourceFile.getName());
            long end = System.currentTimeMillis();
            log.info("压缩完成，共耗时：" + (end - start) + "ms");
        } catch (Exception e){
            e.printStackTrace();
        } finally {
            if (zos != null){
                try {
                    zos.close();
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 递归压缩
     * @param sourceFile 源文件
     * @param zos zip输出流
     * @param name 压缩后的名称
     * @throws Exception 异常
     */
    private static void compress(File sourceFile, ZipOutputStream zos, String name) throws Exception{
        byte[] buf = new byte[2048];
        if (sourceFile.isFile()){
            //向zip输出流中添加一个zip实体
            zos.putNextEntry(new ZipEntry(name));
            //拷贝文件到zip输出流
            int len;
            FileInputStream in = new FileInputStream(sourceFile);
            while ((len = in.read(buf)) != -1){
                zos.write(buf, 0, len);
            }
            zos.closeEntry();
            in.close();
        } else {
            File[] files = sourceFile.listFiles();
            if (files == null || files.length == 0){
                zos.putNextEntry(new ZipEntry(name + "/"));
                zos.closeEntry();
            } else {
                for (File file : files) {
                    compress(file, zos, name + "/" + file.getName());
                }
            }
        }
    }
}
